<!--
 * @Author: Liz.Zheng
 * @Date: 2021-09-29 12:01:15
 * @LastEditTime: 2023-02-20 18:03:24
 * @LastEditors: 郑亚莉 zhengyali@shequ.life
 * @Description: 登录页面
 * @Motto: Write the code. Change the world.
-->
<template>
  <div id="userLogin">
    <section id="logo">
      <img class="logo" :src="logo" />
    </section>
    <!-- 左侧场景图 -->
    <section id="leftContainer" :style="loginBgStyle"></section>
    <!-- 右侧登录框 -->
    <section id="rightContainer">
      <!-- 登录用户信息 -->
      <section id="userLoginForm">
        <!-- 卡片标题 -->
        <a-page-header
          :title="cardTitle ? $t(cardTitle) : '' || $t('user.login.welcome') + systemName"
          @back="backFunction"
          :style="currentStep == 1 ? 'margin-left: -10px' : ''"
          class="card-header"
        >
          <template #backIcon>
            <ArrowLeftOutlined v-if="currentStep > 1" />
          </template>
        </a-page-header>
        <div class="login-tab" v-if="showCodeTab">
          <div
            v-for="tab of TOP_LOGIN_TYPE_LIST"
            :key="tab.type"
            class="item"
            :class="currentLoginType == tab.type ? 'active' : ''"
            @click="handleLoginTypeChange(tab.type)"
          >
            {{ $t(tab.name) }}
          </div>
        </div>
        <!-- <a-tabs
          v-model:activeKey="currentLoginType"
          @change="handleLoginTypeChange()"
          size="small"
          v-if="showCodeTab"
          class="login-tab"
        >
          <a-tab-pane
            v-for="tab of TOP_LOGIN_TYPE_LIST" 
            :key="tab.type"
            :tab="tab.name"
          ></a-tab-pane>
        </a-tabs> -->
        <div class="card-content">
          <template v-if="showWechatQrcode">
            <div class="img-box" v-if="wechatQrcode">
              <img class="qr-code" :src="wechatQrcode" />
              <div class="tips">{{$t('user.login.wx.scan.code')}}</div>
            </div>
          </template>
          <template v-if="showPhoneInput">
            <a-input
              addon-before="+86"
              :placeholder="$t('user.login.phone.placeholder')"
              size="large"
              v-model:value="phoneNumber"
              :max-length="11"
              autofocus
              ref="phoneInput"
            />
            <a-button
              class="submit-btn"
              type="primary"
              size="large"
              @click="getCode()"
              :disabled="phoneUnfinish"
              :loading="getCodeLoading"
            >
              {{ $t("user.login.get.verification.code") }}
            </a-button>
          </template>
          <template v-if="showCodeInput">
            <div class="desc">
              <i18n-t keypath="user.login.six.code.tips" tag="span">
                <template v-slot:phone>
                  <span class="mlr-5 fw-bold">+86{{ phoneNumber }}</span>
                </template>
              </i18n-t>
            </div>
            <div class="code-input">
              <code-input
                @complete="codeFinish"
                :codeValidate="codeValidate"
                :clear="clearTrigger"
              />
              <div class="desc">
                <span
                  style="padding: 0"
                  v-if="timeCount > 0"
                  type="text"
                  key="timer_count"
                >
                  {{$t('user.login.get.verification.code.again', { num: timeCount })}}
                </span>
                <a-button
                  style="padding: 0"
                  class="btn"
                  @click="getCode(true)"
                  type="link"
                  v-else
                  key="retry_get_code"
                >
                  {{ $t("user.login.get.verification.code.new") }}
                </a-button>
              </div>
              <a-button
                class="submit-btn"
                type="primary"
                size="large"
                @click="codeValidate++"
                :disabled="loginBtnDisabled"
                :loading="loading"
              >
                {{ $t("user.login") }}
              </a-button>
            </div>
          </template>
          <template v-if="showPassword">
            <a-input
              :placeholder="$t('user.login.phone.placeholder')"
              size="large"
              v-model:value="phoneNumber"
              :max-length="11"
              autofocus
              ref="phoneInput"
            >
              <template #prefix>
                <MobileOutlined />
              </template>
            </a-input>
            <a-input-password
              class="mt-10"
              :placeholder="$t('user.login.password.placeholder')"
              size="large"
              v-model:value="password"
            >
              <template #prefix>
                <LockOutlined />
              </template>
            </a-input-password>
            <a-button
              class="submit-btn"
              type="primary"
              size="large"
              @click="passwordLogin"
              :disabled="passwordLoginBtnDisabled"
              :loading="loading"
            >
              {{ $t("user.login") }}
            </a-button>
          </template>
          <template v-if="showOrgTypeSelect">
            <div class="org-join-type">
              <img
                src="../../common/images/user/org_empty.png"
                style="width: 200px; height: 200px"
              />
              <div class="mt-5">{{$t('user.login.no.org.tips')}}</div>
              <div class="flex justify-around mt-10">
                <a-button
                  type="primary"
                  size="large"
                  @click="getOrgInfo('join')"
                >
                  <template #icon><cu-icon type="org-jiarujigou" /></template
                  >{{$t('user.login.join.org')}}</a-button
                >
                <a-button
                  type="primary"
                  size="large"
                  @click="getOrgInfo('create')"
                  v-if="config.can_reg_org"
                >
                  <template #icon
                    ><cu-icon type="org-chuangjianjigou" /></template
                  >{{$t('user.login.create.org')}}</a-button
                >
              </div>
            </div>
          </template>
          <template v-if="showOrgJoinForm">
            <div class="org-form">
              <a-space
                direction="vertical"
                class="w-100p"
                v-if="joinOrgType == 'join'"
              >
                <a-input
                  size="large"
                  v-model:value="joinFormData.realname"
                  :placeholder="$t('user.login.name.placeholder')"
                />
                <a-input
                  class="mt-20"
                  size="large"
                  v-model:value="joinFormData.joinCode"
                  :placeholder="$t('user.login.org.invite.placeholder')"
                />
              </a-space>
              <a-space
                direction="vertical"
                class="w-100p"
                v-if="joinOrgType == 'create'"
              >
                <a-input
                  class="mt-20"
                  size="large"
                  v-model:value="createFormData.orgName"
                  :placeholder="$t('user.login.org.name.placeholder')"
                />
                <a-cascader
                  class="mt-20"
                  style="width: 100%"
                  size="large"
                  v-model:value="createFormData.areaValue"
                  :options="areaOptions"
                  :load-data="loadAreaData"
                  :placeholder="$t('user.login.province.placeholder')"
                  change-on-select
                  @change="areaSelectChange"
                />
                <a-select
                  class="mt-20"
                  style="width: 100%"
                  size="large"
                  v-model:value="createFormData.creatOrgType"
                  :placeholder="$t('user.login.org.type.placeholder')"
                  v-if="!type && villageTypeList.length"
                  :options="villageTypeList"
                >
                </a-select>
                <a-input
                  size="large"
                  class="mt-20"
                  v-model:value="createFormData.realname"
                  :placeholder="$t('user.login.name.real.placeholder')"
                />
              </a-space>
              <a-button
                class="submit-btn"
                type="primary"
                size="large"
                @click="orgSubmit()"
                :loading="orgLoading"
              >
                {{ $t("submit") }}
              </a-button>
            </div>
          </template>
        </div>
        <!-- 更多登录方式 -->
        <div class="card-footer" @click.stop>
          <a-checkbox
            v-model:checked="readCheck"
            class="mb-20"
            v-if="canRegOrg && (showPhoneInput || showPassword)"
          >
            {{$t('user.login.agree.to')}}
            <a class="mlr-5" @click.prevent="textModalShow(1)">{{$t('user.login.agree.to.Service')}}</a>
            {{$t('user.login.agree.to.and')}}
            <a class="mlr5" @click.prevent="textModalShow(2)">{{$t('user.login.agree.to.Privacy')}}</a>
          </a-checkbox>
          <template v-if="loginTypeList.length > 1 && showOtherLoginType">
            <Divider>{{ $t("user.login.more") }}</Divider>
            <a-space direction="vertical" class="w-100p">
              <template v-for="item of loginTypeList" :key="item.type">
                <a-button
                  class="btn"
                  shape="round"
                  size="large"
                  @click="handleLoginTypeChange(item.type)"
                  v-if="
                    currentLoginType != item.type &&
                    !(currentLoginType == 'password' && item.type == 'code')
                  "
                >
                  <template #icon>
                    <WechatOutlined v-if="item.type == 'wechat'" />
                    <cu-icon
                      v-if="item.type == 'work_wechat'"
                      type="org-xingzhuang"
                    />
                    <MobileOutlined v-if="item.type == 'code'" />
                    <!-- <LockFilled v-if="item.type == 'password'" /> -->
                  </template>
                  {{ $t(item.name) }}
                </a-button>
              </template>
            </a-space>
          </template>
        </div>
      </section>
      <!-- 腾讯验证码弹层 -->
      <div id="captchaModal" v-show="showCaptcha">
        <iframe
          :src="captchaUrl"
          class="size-100p"
          frameborder="no"
          border="0"
          marginwidth="0"
          marginheight="0"
          scrolling="no"
          allowtransparency="yes"
        ></iframe>
      </div>
      <!-- 图形验证码弹层 -->
      <div class="imageVerify-modal-wrap" v-if="showImageVerify">
        <div class="imageVerify-modal">
          <CloseOutlined
            class="imageVerify-modal-close"
            @click="showImageVerify = false"
          />
          <div class="flex align-center imageVerify-input-wrap">
            <div style="padding-right: 10px">{{$t("user.login.graphic")}}</div>
            <a-input
              :placeholder="$t('user.login.graphic.placeholder')"
              size="large"
              v-model:value="imageVerifyCode"
              :max-length="4"
              autofocus
              ref="imageVerifyInputRef"
              class="imageVerify-input"
            />
            <img
              :src="imageVerifyImg"
              alt=""
              class="imageVerify-img"
              @click="getVerifyImage"
            />
            <SyncOutlined
              class="imageVerify-img-refresh"
              @click="getVerifyImage"
            />
          </div>
          <a-button
            class="imageVerify-btn"
            type="primary"
            size="large"
            @click="getSmsCode()"
            :disabled="!imageVerifyCode || imageVerifyCode.length < 4"
          >
            {{$t('ok')}}
          </a-button>
        </div>
      </div>
    </section>
    <section id="loginFooter" v-if="icp">
      <span @click="toIcp">{{ icp }}</span>
    </section>
    <!-- 用户协议 隐私政策 -->
    <a-modal
      v-model:visible="showTextModal"
      width="800"
      :title="textModalTitle"
      centered
      :footer="null"
    >
      <template v-if="textModalContent.length">
        <div v-for="(text, index) of textModalContent" :key="index">
          {{ text }}
        </div>
      </template>
      <p v-else>--</p>
    </a-modal>
    <!-- 企业微信 -->
    <a-modal
      v-model:visible="workWechatModal"
      :title="$t('user.login.wechat.login')"
      centered
      :footer="null"
      :width="580"
      :bodyStyle="{
        padding: config.can_reg_org ? '60px 0 0 0' : '0 0 0 0',
      }"
      @cancel="workWechatModalClose"
    >
      <template v-if="config.can_reg_org">
        <iframe
          :src="oauthUrl"
          style="width: 580px; height: 440px"
          frameborder="no"
          border="0"
          marginwidth="0"
          marginheight="0"
          scrolling="no"
          allowtransparency="yes"
        ></iframe>
      </template>
      <template v-else>
        <div id="ww_login"></div>
      </template>
    </a-modal>
    <!-- 多语言 -->
    <section id="changeLang">
      <a-dropdown placement="topRight">
        <div class="lang-btn unselect">
          <GlobalOutlined />
          <span class="mlr-5">{{currentLangLabel}}</span>
        </div>
        <template #overlay>
          <a-menu :selectedKeys="[currentLang]" @click="onLangSelect">
            <a-menu-item v-for="item of languageList" :key="item.label"> {{item.name}} </a-menu-item>
          </a-menu>
        </template>
      </a-dropdown>
    </section>
  </div>
</template>

<script>
import {
  GlobalOutlined,
  WechatOutlined,
  MobileOutlined,
  ArrowLeftOutlined,
  LockFilled,
  LockOutlined,
  CloseOutlined,
  SyncOutlined,
} from "@ant-design/icons-vue";
import { Divider, message, Modal } from "ant-design-vue";
import {
  computed,
  defineComponent,
  onUnmounted,
  reactive,
  toRefs,
  watch,
  ref,
  nextTick,
  onMounted,
  watchEffect,
} from "vue";
import { useRoute } from "vue-router";
import utils from "../../common/utils/utils";
import store from "../../store";
import defaultSetting from "../../common/utils/defaultSetting";
import CodeInput from "./modules/CodeInput.vue";
import request from "../../common/utils/request";
import * as ww from "@wecom/jssdk";
import { t } from "@/locale";

export default defineComponent({
  name: "UserLogin",
  components: {
    GlobalOutlined,
    WechatOutlined,
    MobileOutlined,
    ArrowLeftOutlined,
    CodeInput,
    Divider,
    Modal,
    LockFilled,
    LockOutlined,
    CloseOutlined,
    SyncOutlined,
  },
  setup() {
    if (utils.isMobile()) {
      location.replace(
        `${
          defaultSetting.requestDomain || "http://127.0.0.1"
        }/h5_orgs/pages/common/login`
      );
    }
    /**************************************
     * @description: 基础数据
     **************************************/
    const systemName = computed(() => store.getters.basicConfig.system_name);
    const systemIsDemo = computed(
      () => store.getters.basicConfig.system_is_demo
    );

    const currentLangLabel = computed(() => {
      return (state.languageList || []).find((v) => v.label == state.currentLang)?.name || '';
    })

    const systemIsOem = computed(
      () =>
        store.getters.basicConfig.oem_org_id &&
        store.getters.basicConfig.oem_org_id > 0
    );

    const CODE_LOGIN = { type: "code", name: 'user.login.phone'};
    const WECHAT_LOGIN = { type: "wechat", name: 'user.login.wx'};
    const WORK_WECHAT_LOGIN = { type: "work_wechat", name: 'user.login.wechat.login' };
    const TOP_LOGIN_TYPE_LIST = [
      { type: "code", name: 'user.login.type.verification.code'},
      { type: "password", name: 'user.login.type.password'},
    ];
    //登录方式列表
    const loginTypeList = computed(() => {
      let list = [CODE_LOGIN];
      if (
        store.getters.returnConfig.weixin &&
        store.getters.returnConfig.weixin.wechat_appid
      ) {
        list.push(WECHAT_LOGIN);
      }
      if (
        store.getters.returnConfig.work_weixin &&
        store.getters.returnConfig.work_weixin.corp_id
      ) {
        list.push(WORK_WECHAT_LOGIN);
      }

      if (systemIsOem.value && store.getters.basicConfig.can_reg_org) {
        // oem 机构隐藏微信、企业微信登陆方式
        list = list.filter(
          (item) => item.type !== "wechat" && item.type !== "work_wechat"
        );
      }
      return list;
    });

    watch([systemIsDemo, systemIsOem], ([isDemo, isOem]) => {
      if (isDemo && !isOem) {
        handleLoginTypeChange("wechat");
      }
    });
    const loginBgStyle = computed(() =>
      store.getters.basicConfig?.system_name
        ? {
            backgroundImage: `url(${
              store.getters.loginPic ||
              utils.staticPath + "images/common/login_bg.png"
            })`,
          }
        : {}
    );

    const logo = computed(() => store.getters.basicConfig.system_logo);

    const icp = computed(() => store.getters.basicConfig.system_domain_icp);
    const canRegOrg = computed(() => store.getters.basicConfig.can_reg_org)
    const TIMER_COUNT = 60;
    const showCodeTab = computed(
      () =>
        (state.currentLoginType == "code" ||
          state.currentLoginType == "password") &&
        state.currentStep == 1
    );
    // 显示手机号输入
    const phoneInput = ref(null);
    const showPhoneInput = computed(() => {
      return (
        (state.currentLoginType == "code" && state.currentStep == 1) ||
        (state.currentLoginType == "wechat" && state.currentStep == 2) ||
        (state.currentLoginType == "work_wechat" && state.currentStep == 2)
      );
    });
    // 显示验证码输入
    const showCodeInput = computed(
      () =>
        (state.currentLoginType == "code" && state.currentStep == 2) ||
        (state.currentLoginType == "wechat" && state.currentStep == 3) ||
        (state.currentLoginType == "work_wechat" && state.currentStep == 3)
    );
    // 显示微信登录二维码
    const showWechatQrcode = computed(
      () => state.currentLoginType == "wechat" && state.currentStep == 1
    );
    // 显示密码登录
    const showPassword = computed(
      () => state.currentLoginType == "password" && state.currentStep == 1
    );

    // 显示加入或者创建企业选择
    const showOrgTypeSelect = computed(
      () =>
        (state.currentLoginType == "code" && state.currentStep == 3) ||
        (state.currentLoginType == "wechat" && state.currentStep == 4) ||
        (state.currentLoginType == "password" && state.currentStep == 2) ||
        (state.currentLoginType == "work_wechat" && state.currentStep == 4)
    );
    // 显示加入企业表单
    const showOrgJoinForm = computed(
      () =>
        (state.currentLoginType == "code" && state.currentStep == 4) ||
        (state.currentLoginType == "wechat" && state.currentStep == 5) ||
        (state.currentLoginType == "password" && state.currentStep == 3) ||
        (state.currentLoginType == "work_wechat" && state.currentStep == 5)
    );
    // 显示其他登录方式
    const showOtherLoginType = computed(
      () =>
        (state.currentLoginType == "code" && state.currentStep <= 2) ||
        (state.currentLoginType == "wechat" && state.currentStep <= 3) ||
        (state.currentLoginType == "password" && state.currentStep <= 1)
    );
    const TYPE_STEP_SETTING = {
      // 验证码登录
      code: {
        1: {
          type: "phone",
          title: "",
        },
        2: {
          type: "code",
          title: 'user.login.verify.phone',
        },
        3: {
          type: 0,
          title: 'user.login.join.or.create.org',
        },
        4: {
          type: "joinOrgType",
          join: 'user.login.org.invitation.placeholder',
          create: 'user.login.org.perfect',
        },
      },
      // 微信登录
      wechat: {
        1: {
          type: 0,
          title: "",
        },
        2: {
          type: "phone",
          title: 'user.login.phone.bind',
        },
        3: {
          type: "code",
          title: 'user.login.verify.phone',
        },
        4: {
          type: 0,
          title: 'user.login.join.or.create.org',
        },
        5: {
          type: "joinOrgType",
          join: 'user.login.org.invitation.placeholder',
          create: 'user.login.org.perfect',
        },
      },
      // 密码登录
      password: {
        1: {
          type: "phone",
          title: "",
        },
        2: {
          type: 0,
          title: 'user.login.join.or.create.org',
        },
        3: {
          type: "joinOrgType",
          join: 'user.login.org.invitation.placeholder',
          create: 'user.login.org.perfect',
        },
      },
      // 企业微信登录
      work_wechat: {
        1: {
          type: 0,
          title: "",
        },
        2: {
          type: "phone",
          title: 'user.login.phone.bind',
        },
        3: {
          type: "code",
          title: 'user.login.verify.phone',
        },
        4: {
          type: 0,
          title: 'user.login.join.or.create.org',
        },
        5: {
          type: "joinOrgType",
          join: 'user.login.org.invitation.placeholder',
          create: 'user.login.org.perfect',
        },
      },
    };
    const $route = useRoute();

    // 初始数据
    const state = reactive({
      type: $route.query.type,
      showCaptcha: false, // 是否展示腾讯码弹层
      captchaInfo: {}, // 腾讯验证码信息
      captchaUrl: "", // 腾讯验证码iframe地址
      loading: false, // 登录按钮loading
      currentStep: 1, // 当前步骤
      cardTitle: "", // 登录卡片标题
      currentLoginType: "code", // 当前登录方式
      phoneNumber: "", //手机号
      password: "", // 密码
      phoneUnfinish: true, // 获取手机验证码按钮可点击状态
      readCheck: false, // 是否勾选用户协议和隐私政策
      timeCount: TIMER_COUNT, // 重新获取验证码倒计时
      phoneCode: "", // 手机验证码
      loginBtnDisabled: true, // 登录按钮可点击
      codeValidate: 0, // 输入短信验证码后点击下一步主动触发组件的验证码校验,校验完成后由组件触发登录
      clearTrigger: 0, // 触发组件清空短信验证码
      areaOptions: [], //省市区信息
      joinOrgType: "create", // 加入企业的方式： create创建企业 join通过邀请码加入其他企业
      orgLoading: false,
      wechatQrcode: "", // 微信登录二维码
      sceneId: "", // 微信登录sceneId
      showTextModal: false, // 是否展示用户协议等弹窗
      textModalTitle: "", // 协议弹窗名称
      textModalContent: "", //协议弹窗内容
      passwordLoginBtnDisabled: true, // 密码登录按钮可点击
      oauthUrl: "", // 企业微信授权登录地址
      workWechatModal: false,
      villageTypeList: [], //主营业态列表

      showImageVerify: false, // 是否展示图形码弹层
      imageVerifyToken: "", // 图形验证码-token
      imageVerifyCode: null, // 图形验证码-图片
      imageVerifyImg: "", // 图形验证码-输入

      getCodeLoading: false,
      languageList: [], // 语言列表
      currentLang: '',
    });
    // 加入企业需要填写的信息
    const joinFormData = reactive({
      realname: "",
      joinCode: "", // 加入企业邀请码
    });
    // 创建企业需要填写的信息
    const createFormData = reactive({
      realname: "",
      orgName: "",
      areaValue: undefined,
      creatOrgType: undefined,
    });
    const reserFormData = () => {
      joinFormData.realname = "";
      joinFormData.joinCode = "";
      createFormData.realname = "";
      createFormData.orgName = "";
      createFormData.areaValue = undefined;
      createFormData.creatOrgType = undefined;
    };
    // 批量设置数据
    const setState = (data) => {
      for (let key in data) {
        state[key] = data[key];
      }
    };
    // 回到第一步时重置数据
    watch(
      () => state.currentStep,
      (step, preStep) => {
        const currentStepInfo = TYPE_STEP_SETTING[state.currentLoginType][step];
        const preStepInfo = TYPE_STEP_SETTING[state.currentLoginType][preStep];
        // 重置数据
        if (preStepInfo.type == "code" || step == 1) {
          initStep();
        }
        if (state.currentLoginType == "wechat" && step == 1) {
          getWechatQrcode();
        }
        if (currentStepInfo.type == "phone") {
          nextTick(() => {
            phoneInput.value.focus();
          });
        }
        // 卡片标题
        state.cardTitle = currentStepInfo.title
          ? currentStepInfo.title
          : currentStepInfo[state[currentStepInfo.type]];
        // 重置表单
        if (preStepInfo.type == "joinOrgType") {
          reserFormData();
        }
        // 返回时跳过验证码输入界面
        if (currentStepInfo.type == "code" && preStep > step) {
          state.currentStep--;
        }
      }
    );

    const backFunction = () => {
      state.currentStep--;
      // 清除token
      utils.removeStorage("org_token");
      utils.removeStorage("user_token");
    };

    const initStep = () => {
      setState({
        phoneNumber: "",
        phoneUnfinish: true,
        loginBtnDisabled: true,
        phoneCode: "",
        password: "",
      });
      clearTimer();
    };

    /**************************************
     * @description: 手机号验证
     **************************************/
    // 监听电话号码输入
    watch(
      () => state.phoneNumber,
      (phone, prePhone) => {
        phoneFormat(phone, prePhone);
        if (phone.length == 11) {
          // 验证电话号码是否填写正确
          if (utils.phoneReg.test(phone)) {
            state.phoneUnfinish = false;
          } else {
            message.error(t('verify.phone.err'));
          }
        } else if (phone.length < 11 && !state.phoneUnfinish) {
          state.phoneUnfinish = true;
        }
      }
    );
    watch(
      [() => state.phoneUnfinish, () => state.password],
      ([phoneUnfinish, password]) => {
        if (!phoneUnfinish && password) {
          state.passwordLoginBtnDisabled = false;
        } else {
          state.passwordLoginBtnDisabled = true;
        }
      }
    );
    const phoneFormat = (val, preVal) => {
      if (val && val.length > 11) {
        state.phoneNumber = preVal;
        return;
      }
      const reg = /^[0-9]*$/;
      if (reg.test(val)) {
        state.phoneNumber = val;
      } else {
        state.phoneNumber = preVal;
      }
    };

    /**************************************
     * @description: 切换登录方式
     **************************************/
    const handleLoginTypeChange = (type) => {
      if (state.currentStep == 1) {
        initStep();
        if (type == "wechat") {
          getWechatQrcode();
        }
        if (type == "work_wechat") {
          getWorkWechatUrl();
        }
      } else {
        state.currentStep = 1;
      }
      if (type && type !== "work_wechat") {
        state.currentLoginType = type;
      }
      nextTick(() => {
        if (phoneInput.value) {
          phoneInput.value.focus();
        }
      });
    };

    /**************************************
     * @description: 获取企业微信登录链接
     **************************************/
    let wwLogin;
    const getWorkWechatUrl = () => {
      let params = {};
      if (store.getters.basicConfig.can_reg_org) {
        if (store.getters.basicConfig.oem_org_id) {
          params.org_id = store.getters.basicConfig.oem_org_id;
        }
        request
          .get("/third", "/work_wechat/auth", { ...params })
          .then((res) => {
            if (res.oauthUrl) {
              state.oauthUrl = res.oauthUrl;
              state.workWechatModal = true;
            } else {
              message.error(t('user.login.not.supported.wx'));
            }
          });
      } else {
        //本地开发环境加个参数
        if (!defaultSetting.isProduction) {
          params.org_id = 1014;
        }
        if (store.getters.basicConfig.oem_org_id) {
          params.org_id = store.getters.basicConfig.oem_org_id;
        }
        request
          .get("/third", "/work_wechat/auth/param", { ...params })
          .then((res) => {
            if (res.param) {
              state.workWechatModal = true;
              console.log(res.param);
              if (store.getters.basicConfig.oem_org_id) {
                res.param.org_id = store.getters.basicConfig.oem_org_id;
              }
              nextTick(() => {
                // 初始化
                wwLogin = ww.createWWLoginPanel({
                  el: "#ww_login",
                  params: res.param,
                  onCheckWeComLogin({ isWeComLogin }) {
                    console.log(isWeComLogin);
                  },
                  onLoginSuccess({ code }) {
                    console.log({ code });
                  },
                  onLoginFail(err) {
                    console.log(err);
                  },
                });
              });
            }
          });
      }
    };

    const workWechatModalClose = () => {
      state.workWechatModal = false;
      if (wwLogin) {
        wwLogin.unmount();
      }
    };

    /**************************************
     * @description: 获取微信登录二维码
     **************************************/
    let wechatTimer = null;
    const getWechatQrcode = () => {
      third_token = "";
      // if (!state.wechatQrcode) {
      let params = {};
      if (store.getters.basicConfig.oem_org_id) {
        params.org_id = store.getters.basicConfig.oem_org_id;
      }
      request.get("/third", "/wechat/loginCode", { ...params }).then((res) => {
        state.sceneId = res.scene_id;
        state.wechatQrcode = res.url;
        getCodeScanResult();
      });
      // } else {
      //   getCodeScanResult();
      // }
    };
    const getCodeScanResult = () => {
      if (wechatTimer) {
        clearTimer();
      }
      wechatTimer = setInterval(() => {
        checkWechatLogin();
      }, 2000);
    };

    // 检查是否扫码登入成功
    let third_token = "";
    const checkWechatLogin = () => {
      request
        .get("/third", "/pc/checkLogin", {
          scene_id: state.sceneId,
        })
        .then((res) => {
          if (res && res.third_token) {
            clearTimer();
            // 后置登录验证
            third_token = res.third_token;
            let params = {
              third_token: res.third_token,
            };
            const token = $route.query.invite_token;
            if (token) {
              params.token = token;
            }
            store
              .dispatch("UserLogin", {
                server: "/user",
                url: "/login/afterThird",
                params,
              })
              .then((data) => {
                if (data && data.token) {
                  // 已经绑定手机号 获取企业信息后登录
                  getProfile();
                } else {
                  // 去绑定手机号
                  state.currentStep++;
                }
              });
          }
        });
    };

    /**************************************
     * @description: 获取验证码
     **************************************/
    let retry = false;
    const getCode = (retryFlag = false) => {
      if (!canRegOrg.value) {
        state.readCheck = true
      }
      if (!retryFlag && !state.readCheck) {
        message.warning(t('user.login.read.service.tips'));
        return;
      }
      retry = retryFlag;
      const { captcha_type, captcha_qcloud_appid } = store.getters.captcha;
      if (captcha_type == 1) {
        // 显示腾讯验证码
        state.captchaUrl = `${
          defaultSetting.requestDomain
        }/public_web/qcloudCaptcha.html?qcloudAppid=${captcha_qcloud_appid}&t=${Math.random()}`;
        state.showCaptcha = true;
      } else if (captcha_type == 2) {
        // 图形验证码
        getVerifyImage();
      } else {
        // 无需验证则进入短信验证码
        state.getCodeLoading = true;
        getSmsCode();
      }
    };
    let codeTimer = null;
    const getSmsCode = () => {
      const params = {
        phoneCountry: "86",
        phone: state.phoneNumber,
        smsType: "sms_code",
        remark: `org_user_${state.currentLoginType}_login`,
      };
      const { captcha_type } = store.getters.captcha;
      if (captcha_type == 1) {
        params.captchaTicket = state.captchaInfo.ticket;
        params.captchaRandstr = state.captchaInfo.randstr;
      }
      if (captcha_type == 2) {
        params.captchaToken = state.imageVerifyToken;
        params.captchaInput = state.imageVerifyCode;
      }
      const { oem_org_id } = store.getters.basicConfig;
      if (oem_org_id) {
        params.org_id = oem_org_id;
      }
      request
        .post("/message", "/sms/sendSmsCodeGuest", params)
        .then(() => {
          message.success(t('user.login.code.sent'));
          state.showImageVerify = false;
          state.imageVerifyCode = null;
          state.imageVerifyImg = "";
          state.imageVerifyToken = "";
          if (retry) {
            retry = false;
          } else {
            state.currentStep++;
          }
          codeTimer && clearTimer();
          state.timeCount = TIMER_COUNT;
          codeTimer = setInterval(() => {
            if (state.timeCount == 0) {
              clearTimer();
            }
            state.timeCount--;
          }, 1000);
        })
        .catch((err) => {
          // 如果是图形验证错误，才自动重新获取图形验证码
          if (captcha_type == 2) {
            message.error(err.msg);
            state.imageVerifyCode = null;
            getVerifyImage();
          }
        })
        .finally(() => {
          state.getCodeLoading = false;
        });
    };
    const clearTimer = () => {
      if (codeTimer) {
        clearInterval(codeTimer);
        codeTimer = null;
      }
      if (wechatTimer) {
        clearInterval(wechatTimer);
        wechatTimer = null;
      }
    };

    /**************************************
     * @description: 监听验证码输入
     **************************************/
    // 验证码是否输入完成
    const codeFinish = (val) => {
      state.phoneCode = val;
      state.loginBtnDisabled = false;
      toLogin();
    };

    /**************************************
     * @description: 登录
     **************************************/
    // 密码登录
    const passwordLogin = () => {
      if (canRegOrg.value) {
        if (!state.readCheck) {
          message.warning(t('user.login.read.service.tips'));
          return;
        }
      }
      
      loginAction({
        params: {
          phone_country: "86",
          phone: state.phoneNumber,
          password: state.password,
        },
        requestUrl: "/login/pwd",
      });
    };
    // 去登陆
    const toLogin = () => {
      loginAction({
        params: {
          phone_country: "86",
          phone: state.phoneNumber,
          code: state.phoneCode,
        },
        requestUrl: "/login/reg",
      });
    };
    const loginAction = ({ params, requestUrl }) => {
      const token = $route.query.invite_token;
      if (token) {
        params.token = token;
      }
      if (third_token) {
        params.third_token = third_token;
      }
      state.loading = true;
      store
        .dispatch("UserLogin", {
          server: "/user",
          url: requestUrl,
          params,
        })
        .then(() => {
          getProfile();
        })
        .catch((err) => {
          // 验证码不对等错误
          state.clearTrigger++;
        })
        .finally(() => {
          state.loading = false;
        });
    };
    // 获取用户信息
    const getProfile = () => {
      store
        .dispatch("GetProfile")
        .then((res) => {
          if (res.last_org_id == 0) {
            // 未加入企业
            state.currentStep++;
            if (res.sharer && res.sharer.join_code) {
              // 是通过已有企业分享链接进来的已有企业码信息，直接跳转至加入企业步骤
              joinFormData.joinCode = res.sharer.join_code;
              getOrgInfo("join");
            }
          } else {
            // 已加入企业
            loginSuccess(res);
          }
        })
        .catch((err) => {
          if (err.code == 2001 || err.code == 2002) {
            Modal.warning({
              content: err.msg,
              centered: true,
              onOk: () => {
                if (err.code == 2001) {
                  // 企业正在审核中或未分配角色
                  state.currentStep = 1;
                  utils.clearStorage();
                }
                if (err.code == 2002) {
                  // 加入企业被拒绝（非审核状态）
                  state.currentStep++;
                }
              },
            });
          }
        });
    };
    // 获取企业相关信息
    const getOrgInfo = (type) => {
      state.joinOrgType = type;
      state.currentStep++;
      if (type == "create") {
        if (!state.areaOptions.length) {
          request.get("/public", "/district/province_list").then((res) => {
            if (res.list) {
              state.areaOptions = res.list.map((item) => ({
                value: item.area_code,
                label: item.short_name,
                level: 1,
                isLeaf: false,
              }));
            }
          });
        }
        if (!state.villageTypeList.length) {
          request.get("/village", "/village/type/list").then((res) => {
            state.villageTypeList = res.list.map((item) => ({
              label: item.name,
              value: item.alias,
            }));
            createFormData.creatOrgType = state.villageTypeList[0].value;
          });
        } else {
          createFormData.creatOrgType = state.villageTypeList[0].value;
        }
      }
    };
    // 动态加载省市区信息
    const loadAreaData = (selectedOptions) => {
      const targetOption = selectedOptions[selectedOptions.length - 1];
      targetOption.loading = true;
      targetOption.loading = false;
      const requestUrl =
        targetOption.level == 1
          ? "/district/city_list"
          : "/district/district_list";
      const params =
        targetOption.level == 1
          ? { province_id: targetOption.value }
          : { city_id: targetOption.value };
      request.get("/public", requestUrl, params).then((res) => {
        if (res.list) {
          targetOption.children = res.list.map((item) => ({
            label: item.short_name,
            value: item.area_code,
            level: targetOption.level + 1,
            isLeaf: targetOption.level > 1,
          }));
        }
      });
      state.areaOptions = [...state.areaOptions];
    };

    // 监听省市区选择
    let selectedAreaOptions = [];
    const areaSelectChange = (value, selectedOptions) => {
      selectedAreaOptions = selectedOptions;
    };

    // 登录成功
    const loginSuccess = (res) => {
      store.dispatch("ClearCurrentMenu");
      const { redirect } = $route.query;
      let url = redirect;
      if (res.org_info.homeUrl) {
        url = res.org_info.homeUrl.url;
      }
      url = decodeURIComponent(url || "/index");
      utils.goUrl(url, "replace");
    };

    /**************************************
     * @description: 加入或者创建企业
     **************************************/
    const orgSubmit = () => {
      let requestUrl = "";
      let params = {};
      if (state.joinOrgType == "join") {
        for (let key in joinFormData) {
          if (!joinFormData[key]) {
            message.warning(t('verify.form.err'));
            return;
          }
        }
        requestUrl = "/user/orgJoin";
        params = {
          join_code: joinFormData.joinCode,
          realname: joinFormData.realname,
          needMsg: true,
        };
      }
      if (state.joinOrgType == "create") {
        if (state.type) {
          createFormData.creatOrgType = state.type;
        }
        for (let key in createFormData) {
          if (!createFormData[key]) {
            message.warning(t('verify.form.err'));
            return;
          }
          if (key == "areaValue" && createFormData[key].length < 2) {
            message.warning(t('user.login.org.region.err'));
            return;
          }
        }
        requestUrl = "/user/orgCreate";
        params = {
          company: createFormData.orgName,
          province_id: createFormData.areaValue[0],
          city_id: createFormData.areaValue[1],
          type: createFormData.creatOrgType,
          realname: createFormData.realname,
          needMsg: true,
        };
        const districtName = `${selectedAreaOptions[0].label},${selectedAreaOptions[1].label}`;
        params.district_name = districtName;
      }
      state.orgLoading = true;
      request
        .post("/org", requestUrl, params)
        .then((res) => {
          Modal.success({
            content: res.msg,
            centered: true,
            onOk: () => {
              state.currentStep = 1;
              // 清除token
              utils.removeStorage("org_token");
              utils.removeStorage("user_token");
            },
          });
        })
        .finally(() => {
          state.orgLoading = false;
        });
    };

    /**************************************
     * @description: 查看用户协议和隐私政策
     **************************************/
    const textModalShow = (type) => {
      const { org } = store.getters.returnConfig;
      if (org) {
        const text = type == 1 ? org.user_agreement : org.privacy_agreement;
        if (text) {
          state.textModalContent = text.split("\n");
        }
        state.textModalTitle = type == 1 ? t('user.login.agree.to.Service') : t('user.login.agree.to.Privacy');
        state.showTextModal = true;
      } else {
        message.info(t('verify.no.config'));
      }
    };

    // icp
    const toIcp = () => {
      window.open("https://beian.miit.gov.cn/");
    };

    const getLanguages = () => {
      request
        .get("/public", "/system/language", {})
        .then((res) => {
          state.languageList = res?.list || [];
        })
        .finally(() => {

        });
    };

    const onLangSelect = ({ key }) => {
      utils.setStorage('lang', key).then(() => {
        store.dispatch('getConfig');
      })
    };

    /**************************************
     * @description: 初始化
     **************************************/
    const init = () => {
      //  监听腾讯验证码message
      window.addEventListener(
        "message",
        (e) => {
          if (e.data) {
            const { type } = e.data;
            if (type === "qcloudCaptchaResult") {
              state.showCaptcha = false;
              const { res } = e.data;
              if (res && res.ticket && res.randstr) {
                state.captchaInfo = res;
                getSmsCode();
              }
            }
          }
        },
        false
      );
      if (systemIsDemo.value && !systemIsOem.value) {
        handleLoginTypeChange("wechat");
      };
      state.currentLang = store.getters.lang;
      getLanguages();
    };

    watchEffect(() => {
      state.currentLang = store.getters.lang;
    })

    init();

    const config = computed(() => store.getters.basicConfig);

    onMounted(() => {
    
    });

    onUnmounted(() => {
      clearTimer();
      if (wwLogin) {
        wwLogin.unmount();
      }
    });

    const imageVerifyInputRef = ref(null);

    const getVerifyImage = () => {
      request.get("/message", "/verify/image", {}).then((res) => {
        if (res.token && res.image) {
          state.imageVerifyToken = res.token;
          state.imageVerifyImg = res.image;
          state.showImageVerify = true;
          nextTick(() => {
            if (imageVerifyInputRef.value) {
              imageVerifyInputRef.value.focus();
            }
          });
        }
      });
    };

    return {
      ...toRefs(state),
      logo,
      icp,
      loginTypeList,
      showOtherLoginType,
      TOP_LOGIN_TYPE_LIST,
      systemName,
      phoneInput,
      showPhoneInput,
      showCodeInput,
      showWechatQrcode,
      showOrgTypeSelect,
      showOrgJoinForm,
      joinFormData,
      createFormData,
      TIMER_COUNT,
      loadAreaData,
      areaSelectChange,
      handleLoginTypeChange,
      getCode,
      codeFinish,
      getOrgInfo,
      orgSubmit,
      textModalShow,
      showPassword,
      passwordLogin,
      showCodeTab,
      toIcp,
      config,
      loginBgStyle,
      getVerifyImage,
      imageVerifyInputRef,
      getSmsCode,

      workWechatModalClose,
      backFunction,
      currentLangLabel,
      onLangSelect,
      canRegOrg
    };
  },
});
</script>

<style lang="less" scoped>
@import "./login.less";

.imageVerify-modal-wrap {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgba(0, 0, 0, 0.5);

  .imageVerify-modal {
    width: 444px;
    height: 230px;
    background-color: #fff;
    border-radius: 4px;
    padding: 60px 30px 30px 30px;
    position: relative;

    .imageVerify-modal-close {
      position: absolute;
      top: 0;
      right: 0;
      cursor: pointer;
      font-size: 18px;
      padding: 15px;
    }

    .imageVerify-input-wrap {
      border-bottom: 1px solid #f1f1f1;
      padding-bottom: 10px;

      :deep(.imageVerify-input) {
        flex: 1;
        border: none;
        box-shadow: none;
        border-radius: 0;
      }

      .imageVerify-img {
        width: 117px;
        height: 36px;
        margin-left: 10px;
        border: 2px solid #f1f1f1;
      }

      .imageVerify-img-refresh {
        padding: 0 6px;
        margin-left: 5px;
        font-size: 16px;
        cursor: pointer;
      }
    }

    .imageVerify-btn {
      margin-top: 40px;
      width: 100%;
    }
  }
}

#ww_login {
  width: 580px;
  height: 440px;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
